package com.starsea.book.ui.book.search

import android.app.Application
import android.os.Handler
import android.os.Looper
import androidx.collection.arrayMapOf
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.starsea.book.base.BaseViewModel
import com.starsea.book.constant.AppConst
import com.starsea.book.constant.AppLog
import com.starsea.book.data.appDb
import com.starsea.book.data.entities.SearchBook
import com.starsea.book.data.entities.SearchKeyword
import com.starsea.book.help.config.AppConfig
import com.starsea.book.help.http.newCallResponseBody
import com.starsea.book.help.http.okHttpClient
import com.starsea.book.help.http.postJson
import com.starsea.book.help.http.text
import com.starsea.book.ui.newpage.entity.BaseEntity
import com.starsea.book.ui.newpage.entity.HomeDataEntity
import com.starsea.book.ui.newpage.utils.gsonList
import com.starsea.book.utils.ConflateLiveData
import com.starsea.book.utils.LogUtils
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.mapLatest
import java.util.Collections

@OptIn(ExperimentalCoroutinesApi::class)
class SearchViewModel(application: Application) : BaseViewModel(application) {
    val handler = Handler(Looper.getMainLooper())
    val bookshelf: MutableSet<String> = Collections.synchronizedSet(hashSetOf<String>())
    val upAdapterLiveData = MutableLiveData<String>()
    var searchBookLiveData = ConflateLiveData<List<SearchBook>>(1000)
    val searchScope: SearchScope = SearchScope(AppConfig.searchScope)
    var searchFinishLiveData = MutableLiveData<Boolean>()
    var isSearchLiveData = MutableLiveData<Boolean>()
    var searchKey: String = ""
    private var searchID = 0L
//    private val searchModel = SearchModel(viewModelScope, object : SearchModel.CallBack {
//
//        override fun getSearchScope(): SearchScope {
//            return searchScope
//        }
//
//        override fun onSearchStart() {
//            isSearchLiveData.postValue(true)
//        }
//
//        override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
//            searchBookLiveData.postValue(searchBooks)
//        }
//
//        override fun onSearchFinish(isEmpty: Boolean) {
//            isSearchLiveData.postValue(false)
//            searchFinishLiveData.postValue(isEmpty)
//        }
//
//        override fun onSearchCancel(exception: Exception?) {
//            isSearchLiveData.postValue(false)
//            exception?.let {
//                context.toastOnUi(it.localizedMessage)
//            }
//        }
//
//    })

    init {
        execute {
            appDb.bookDao.flowAll().mapLatest { books ->
                books.map { "${it.name}-${it.author}" }
            }.collect {
                bookshelf.clear()
                bookshelf.addAll(it)
                upAdapterLiveData.postValue("isInBookshelf")
            }
        }.onError {
            AppLog.put("加载书架数据失败", it)
        }
    }

    val searchResult = MutableLiveData<BaseEntity<MutableList<HomeDataEntity>>>()

    /**
     * 开始搜索
     */
    fun search(key: String, pageNo: Int) {
        execute {
            if ((searchKey == key) || key.isNotEmpty()) {
//                searchModel.cancelSearch()
                searchID = System.currentTimeMillis()
                searchKey = key
            }
            if (searchKey.isEmpty()) {
                return@execute
            }
            val map: MutableMap<String, String> = arrayMapOf()
            map["keyword"] = key
            map["pageNo"] = pageNo.toString()
            map["pageSize"] = 10.toString()
            val json = Gson().toJson(map)
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/book/search_book"))
                    .postJson(json)
            }.text().let {
                LogUtils.e(">>>", ">>.${it}")
                val entity: BaseEntity<MutableList<HomeDataEntity>> =
                    it.gsonList(HomeDataEntity::class.java)
                searchResult.postValue(entity)
            }

        }
    }

    /**
     * 停止搜索
     */
    fun stop() {
//        searchModel.cancelSearch()
    }

    /**
     * 保存搜索关键字
     */
    fun saveSearchKey(key: String) {
        execute {
            appDb.searchKeywordDao.get(key)?.let {
                it.usage = it.usage + 1
                it.lastUseTime = System.currentTimeMillis()
                appDb.searchKeywordDao.update(it)
            } ?: appDb.searchKeywordDao.insert(SearchKeyword(key, 1))
        }
    }

    /**
     * 清楚搜索关键字
     */
    fun clearHistory() {
        execute {
            appDb.searchKeywordDao.deleteAll()
        }
    }

    fun deleteHistory(searchKeyword: SearchKeyword) {
        execute {
            appDb.searchKeywordDao.delete(searchKeyword)
        }
    }

    override fun onCleared() {
        super.onCleared()
//        searchModel.close()
    }

}
